import flash.filters.DropShadowFilter;

import com.yourdomain.spreadshop.gui.GUI;
import com.yourdomain.spreadshop.gui.mod.lib.Module;

import net.spreadshirt.logger.Logger;

/**
 * The MouseCursor class attaches some animation clips
 * to the mouse coursor.
 */
class com.yourdomain.spreadshop.gui.mod.MouseCursor {

	// The reference to the swf file.
	private static var _SWF:String = "spreadshop_mouseCursor.swf";

	// The reference to the GUI main class .
	private var _gui:GUI;

	// The movie clip container.
	private var _clip:MovieClip;

	// Some clip settings.	private var _clipReceiving:MovieClip;
	private static var _clipReceivingLevel:Number = 10;
	private var _clipScrolling:MovieClip;
	private static var _clipScrollingLevel:Number = 20;
	private var _clipDragging:MovieClip;
	private static var _clipDraggingLevel:Number = 30;

	private var _clipTooltip:MovieClip;
	private static var _clipTooltipLevel:Number = 40;	private static var _clipTooltipDelay:Number = 10;
	// Number of Transmissions in progress.
	private var _nTransmissons:Number;

	/**
	 * MouseCursor Constructor
	 */
	public function MouseCursor(
		gui:GUI,
		clip:MovieClip,
		level:Number
	) {
		// Connects with the GUI instance.
		_gui = gui;
		// create clip and set position on stage
		_clip = clip.createEmptyMovieClip("mc_mousecursor", level);
		// create listener to watch loading in progress
		var mclListener:Object = new Object();
		mclListener.timer = [0, 0];
		mclListener.onLoadStart = function(target:MovieClip):Void {
		    this.timer[0] = getTimer();
			Logger.getLog().info("GUI - MouseCursor: start loading");
		};
		mclListener.onLoadComplete = function(target:MovieClip):Void {
			this.timer[1] = getTimer();
		};
		mclListener.mouseCursor = this;		mclListener.onLoadInit = function(target:MovieClip):Void {
			var timer:Number = this.timer[1] - this.timer[0];
			var bytes:Number = target.getBytesLoaded();
			Logger.getLog().info("GUI - MouseCursor: "
				+ bytes +" Bytes loaded in "+ timer +" ms.");
			this.mouseCursor.setup();
		};
		// Create loader an attach listener.
		var mcLoader:MovieClipLoader = new MovieClipLoader();
		mcLoader.addListener(mclListener);
		mcLoader.loadClip(_gui.swf_path + _SWF, _clip);
	}

	/**
	 * Setup
	 */
	private function setup():Void {
		_gui.initModuleDone("initMouseCursor");
		_nTransmissons = 0;
	}

	/**
	 * Shows the number of transmissions in the transmission indicator.
	 */
	private function showNumberOfTransmissions():Void {
		// Show number of transmissions.
		var strTrnsmssns:String = (_nTransmissons > 0)
			? String(_nTransmissons)
			: ""
		;
		_clipReceiving.tf.text = strTrnsmssns;
	}

	/**
	 * Starts the transmission indicator.
	 */
	public function startTransmissionIndicator():Void {
		// Create the transmission indicator movie clip.
		if(_clipReceiving._totalframes == undefined) {
			_clipReceiving = _clip.attachMovie(
				"receiving",				"mc_receiving",
				_clipReceivingLevel,
				{ _visible: false }
			);
			// Attach clip to mouse cursor position.
			_clipReceiving.onEnterFrame = setPosition();			_clipReceiving.onEnterFrame();
			_clipReceiving._visible = true;
		}
		// Increase the number of transmissions in progress.
		_nTransmissons++;
		// Show number of transmissions in progress.
		showNumberOfTransmissions();
	}

	/**
	 * Stops the transmission indicator.
	 */
	public function stopTransmissionIndicator():Void {
		// Decrease number of transmissions in progress.
		if(_nTransmissons > 0) {
			_nTransmissons--;
		}
		// Show number of transmissions in progress.
		showNumberOfTransmissions();
		// Remove the movie clip if there are no more transmissions.
		if(_nTransmissons < 1 && _clipReceiving != undefined) {
			removeClip(_clipReceiving);		}
	}

	/**
	 * Starts the dragging indicator.
	 */
	public function startDraggingIndicator():Void {
		// Creates the scrolling indicator movie clip.
		_clipDragging = _clip.attachMovie(
			"dragging",
			"mc_dragging",
			_clipDraggingLevel,
			{ _visible: false }
		);
		// Attaches the movie clip to the position of the mouse cursor.
		_clipDragging.onEnterFrame = setPosition();
		_clipDragging.onEnterFrame();
		_clipDragging._visible = true;
	}

	/**
	 * Stops the dragging indicator.
	 */
	public function stopDraggingIndicator():Void {
		// Remove the scrolling indicator movie clip.
		_clipDragging.removeMovieClip();
	}

	/**
	 * Starts the scrolling indicator.
	 */
	public function startScrollingIndicator():Void {
		// Creates the scrolling indicator movie clip.
		_clipScrolling = _clip.attachMovie(
			"scrolling",
			"mc_scrolling",
			_clipScrollingLevel,
			{ _visible: false }
		);
		// Attaches the movie clip to the position of the mouse cursor.
		_clipScrolling.onEnterFrame = setPosition();
		_clipScrolling.onEnterFrame();
		_clipScrolling._visible = true;
	}

	/**
	 * Stops the scrolling indicator.
	 */
	public function stopScrollingIndicator():Void {
		// Remove the scrolling indicator movie clip.
		_clipScrolling.removeMovieClip();
	}

	/**
	 * Shows the tooltip.
	 */
	public function startTooltip(str:String):Void {
		// Creates the tooltip movie clip.
		_clipTooltip = _clip.attachMovie(
			"tooltip",
			"mc_tooltip",
			_clipTooltipLevel,
			{ _visible: false }
		);
		// Attaches the movie clip to the position of the mouse cursor.
		_clipTooltip.onEnterFrame = setPosition();
		_clipTooltip.onEnterFrame();
		var tooltip:MovieClip = _clipTooltip.tooltip;
		tooltip.tf.htmlText = str;
		var width:Number = tooltip.tf.textWidth >> 0;
		tooltip.center._width = width;		tooltip.end._x = tooltip.center._x + width;
		// Setup the filter effects.
	    var filShadow:DropShadowFilter = Module.FILTER_SUB_SHADOW;
	    var filArray:Array = new Array();
	    filArray.push(filShadow);
	    tooltip.filters = filArray;
	    tooltip.cacheAsBitmap = true;
	    // A function to fade in the movie clip.
		tooltip.show = function():Void {
			this._parent._visible = true;
			this._alpha = 0;
			this.onEnterFrame = function():Void {
				this._alpha += 10;
				if(this._alpha > 90) {
					this._alpha = 100;
					delete this.onEnterFrame;
				}
			};
		};
		tooltip.delay = _clipTooltipDelay;
		tooltip.onEnterFrame = function():Void {
			if(--this.delay < 0) {
				this.onEnterFrame = this.show;
			}
		};
	}

	/**
	 * Hides the tooltip.
	 */
	public function stopTooltip():Void {
		var tooltip:MovieClip = _clipTooltip.tooltip;
	    // The FadeOut method.
		tooltip.hide = function():Void {
			this.onEnterFrame = function():Void {
				this._alpha -= 10;
				if(this._alpha < 10) {
					this._alpha = 0;
					delete this.onEnterFrame;
					// Remove the tooltip movie clip.
					this._parent.removeMovieClip();
				}
			};
		};		tooltip.onEnterFrame = tooltip.hide;
	}

	/**
	 * Returns a simple function that sets the movie clips position
	 * to the position of the mouse cursor.
	 *
	 * @return	 A Function.
	 */
	static private function setPosition():Function {
		var fnc:Function = function() {
			this._x = this._parent._xmouse;
			this._y = this._parent._ymouse;
		};
		return fnc;
	};

	/**
	 * A simple function that removes the movie clip
	 * after the clips animation is done.
	 */
	static private function removeClip(clip:MovieClip):Void {
		clip.setPosition = setPosition();
		clip.onEnterFrame = function():Void {
			this.setPosition();
			if(this._currentframe == 1) {
				// Remove movie clip.
				this.removeMovieClip();
			}
		};
	}

}
